package com.qikux.controller;

import cn.hutool.extra.mail.MailUtil;
import com.qikux.constraint.RssConst;
import com.qikux.entity.User;
import com.qikux.service.UserService;
import com.qikux.utils.RSAUtils;
import com.qikux.utils.UploadUtils;
import com.qikux.vo.R;
import org.haredot.annotation.*;
import org.haredot.utils.WebUtils;
import org.haredot.web.ModelAndView;
import org.haredot.web.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

@Controller
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService ;

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String register() {
        return "register" ;
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public ModelAndView register(@RequestParam("tel") String tel ,
                                 @RequestParam("password") String password,
                                 @RequestParam("email") String email ,
                                 HttpSession session) {

        // 将页面接收到的参数，存储到 实体对象
        User user = User.builder()
                .tel(tel)
                .password(password)
                .email(email).build();

        //  调用业务逻辑层完成业务处理
        R<Long> resultVo = userService.register(user);

        // 根据注册的结果 ，决定如何跳转页面
        if (resultVo.isSuccess()) {
            // 跳转到 注册的第二步
            session.setAttribute("uid" , resultVo.getData());
            return new ModelAndView("redirect:/user/next");
        }
        // 如果失败了， 跳回第一步、并回显失败的原因
        ModelAndView mav = new ModelAndView("register") ;
        mav.addObject("user" , user);
        mav.addObject("error", resultVo.getMessage());

        return mav ;
    }

    @RequestMapping(value = "/next", method = RequestMethod.GET)
    public ModelAndView next(HttpSession session) {
        // 获取 从第一步 得到的 UID
        Long uid = (Long)session.getAttribute("uid");

        // 如果 得不到该值，跳转到第一步
        if (uid == null) {
            return new ModelAndView("redirect:/user/register");
        }

        // 如果 有值，则正常跳转到 第二步
        ModelAndView mav = new ModelAndView("next_reg");
        mav.addObject("uid", uid);

        return mav ;
    }

    @RequestMapping(value = "/next", method = RequestMethod.POST)
    public ModelAndView next(@RequestParam(value = "photo", required = false) String photo,
                             @RequestParam(value = "birth", required = false) String birth,
                             @RequestParam(value = "nickName", required = false) String nickName,
                             @RequestParam(value = "realName", required = false) String realName,
                             @RequestParam(value = "sex", required = false) String sex,
                             @RequestParam(value = "uid") Long id,
                             HttpSession session) {

        // 检查 id 是否和 session 中存储的ID 是否一致
        if (!Objects.equals(id, session.getAttribute("uid"))) {
            // 跳转到注册第一步
            return new ModelAndView("redirect:/user/register");
        }
        /**
         * 处理日期
         */
        LocalDate birthday = null ;
        if (birth != null && !"".equals(birth)) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            birthday = LocalDate.parse(birth, dateTimeFormatter);
        }

        // 将数据进行封装到 User 对象中
        User user = User.builder()
                .id(id)
                .photo(photo)
                .birth(birthday)
                .nickName(nickName)
                .realName(realName)
                .sex(sex)
                .build();

        // 进行 数据的 修改
        R<?> ret = userService.modifyBaseUser(user);

        // 如果 操作成功
        if (ret.isSuccess()) {
            // 跳转到 第三步 ，并携带 uid
            return new ModelAndView("redirect:/user/success") ;
        }

        return new ModelAndView("next_reg") ;
    }



    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody R<String> upload(@RequestPart("photo") Part part) throws Exception {
        // 使用工具类 将文件上传到 指定的目录
        String path = UploadUtils.upload(part, RssConst.USER_PHOTO_DIR) ;
        // 响应数据
        return  R.<String>ok().data(path);
    }

    @RequestMapping(value = "/active", method = RequestMethod.GET)
    public ModelAndView activeAccount(@RequestParam("uid") Long uid , @RequestParam("sign") String sign) {
        // 进行数字认证
        String message = "uid=" + uid + "&site=haredot" ;

        boolean verify = RSAUtils.verify(message, sign);

        if (!verify) {
            throw new RuntimeException("请勿篡改数据");
        }
        // 激活账户
        R<?> ret = userService.activeUser(uid);

        if (ret.isSuccess()) {
            // 跳转到登录页面
            WebUtils.getSession().removeAttribute("uid");
            return new ModelAndView("redirect:/login") ;
        }
        return new ModelAndView("error") ;
    }


    @RequestMapping(value = "/success", method = RequestMethod.GET)
    public ModelAndView success(HttpSession session) throws Exception {

        ModelAndView mav = new ModelAndView("success");
        // 从 session中 获取当前注册的用户
        Long uid = (Long) session.getAttribute("uid");
        // 查询 数据
        R<User> ret = userService.queryUser(uid);

        if (ret.isSuccess()) {
            User user = ret.getData();
            // 获取注册人的 邮箱地址
            String email = user.getEmail() ;

            String tel = user.getTel() ;
            String currentTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());

            HttpServletRequest request = WebUtils.getRequest();

            // 对用户名进行数字签名
            String message = "uid=" + uid + "&site=haredot" ;
            String sign = RSAUtils.sign(message);

            String link = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                    + request.getContextPath() + "/user/active?uid=" +  uid + "&sign=" + URLEncoder.encode(sign, StandardCharsets.UTF_8);
            // 发送消息
            String content = """
                    <div>
                       <p>尊敬的<b>{0}</b>用户:</p>
                       <p>您于{1}成为了本网站的用户成员，请点击下方链接激活您的账户。</p>
                       <a href="{2}">{3}</a>
                    </div>
                    """ ;
            // 格式化字符串
            MessageFormat messageFormat = new MessageFormat(content) ;

            String body = messageFormat.format(new Object[] {tel, currentTime, link, link}) ;

            // 发送邮件
            MailUtil.send(email, "【爱下载资源分享平台】-账户激活", body, true) ;

            mav.addObject("user", user);
        }
        return mav ;
    }
}
